===================================================================
RCS file: ./src/s/linux.h,v
retrieving revision 1.1
diff -b -B -C 3 -r1.1 ./src/s/linux.h
*** ./src/s/linux.h	1995/12/30 18:56:50	1.1
--- ./src/s/linux.h	1996/01/06 05:10:22
***************
*** 200,205 ****
--- 199,210 ----
  #define LIB_GCC
  #define LIB_STANDARD -lgcc -lc -lgcc /usr/lib/crtn.o
  #endif
+ 
+ #ifdef HAVE_LIBGPM
+ #define LIBS_GPM -lgpm
+ #else
+ #define LIBS_GPM
+ #endif /* HAVE_LIBGPM */
  
  /* Don't use -g in test compiles in configure.
     This is so we will use the same shared libs for that linking
===================================================================
RCS file: ./src/Makefile.in.in,v
retrieving revision 1.1
diff -b -B -C 3 -r1.1 ./src/Makefile.in.in
*** ./src/Makefile.in.in	1995/12/30 19:06:07	1.1
--- ./src/Makefile.in.in	1996/01/06 05:04:16
***************
*** 471,481 ****
  #define MSDOS_OBJ
  #endif
  
  
  /* lastfile must follow all files
     whose initialized data areas should be dumped as pure by dump-emacs. */
  obj=    dispnew.o frame.o scroll.o xdisp.o window.o \
! 	cm.o term.o $(XOBJ) \
  	emacs.o keyboard.o macros.o keymap.o sysdep.o \
  	buffer.o filelock.o insdel.o marker.o INTERVAL_OBJ \
  	minibuf.o fileio.o dired.o filemode.o \
--- 471,488 ----
  #define MSDOS_OBJ
  #endif
  
+ #ifdef HAVE_LIBGPM
+ #define GPM_OBJ gpmevent.o
+ #define GPM_SRC gpmevent.c
+ #else
+ #define GPM_OBJ
+ #define GPM_SRC
+ #endif
  
  /* lastfile must follow all files
     whose initialized data areas should be dumped as pure by dump-emacs. */
  obj=    dispnew.o frame.o scroll.o xdisp.o window.o \
! 	cm.o term.o $(XOBJ) GPM_OBJ \
  	emacs.o keyboard.o macros.o keymap.o sysdep.o \
  	buffer.o filelock.o insdel.o marker.o INTERVAL_OBJ \
  	minibuf.o fileio.o dired.o filemode.o \
***************
*** 484,491 ****
  	eval.o floatfns.o fns.o print.o lread.o \
  	abbrev.o syntax.o UNEXEC mocklisp.o bytecode.o \
  	process.o callproc.o \
! 	region-cache.o \
! 	doprnt.o strftime.o MKTIME_OBJ GETLOADAVG_OBJ MSDOS_OBJ
  
  /* Object files used on some machine or other.
     These go in the DOC file on all machines
--- 491,498 ----
  	eval.o floatfns.o fns.o print.o lread.o \
  	abbrev.o syntax.o UNEXEC mocklisp.o bytecode.o \
  	process.o callproc.o \
! 	region-cache.o doprnt.o strftime.o \
! 	MKTIME_OBJ GETLOADAVG_OBJ MSDOS_OBJ 
  
  /* Object files used on some machine or other.
     These go in the DOC file on all machines
***************
*** 648,654 ****
     Note that SunOS needs -lm to come before -lc; otherwise, you get
     duplicated symbols.  If the standard libraries were compiled
     with GCC, we might need gnulib again after them.  */
! LIBES = $(LIBX) LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \
     LIBS_DEBUG $(GNULIB_VAR) LIB_MATH LIB_STANDARD $(GNULIB_VAR)
  
  /* Enable recompilation of certain other files depending on system type.  */
--- 655,661 ----
     Note that SunOS needs -lm to come before -lc; otherwise, you get
     duplicated symbols.  If the standard libraries were compiled
     with GCC, we might need gnulib again after them.  */
! LIBES = $(LIBX) LIBS_GPM LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \
     LIBS_DEBUG $(GNULIB_VAR) LIB_MATH LIB_STANDARD $(GNULIB_VAR)
  
  /* Enable recompilation of certain other files depending on system type.  */
***************
*** 846,851 ****
--- 853,860 ----
     it is so often changed in ways that do not require any recompilation
     and so rarely changed in ways that do require any.  */
  
+ gpmevent.o: gpmevent.c window.h blockinput.h termhooks.h termopts.h frame.h \
+ 	sysselect.h syssignal.h
  abbrev.o: abbrev.c buffer.h commands.h $(config_h) 
  buffer.o: buffer.c buffer.h region-cache.h commands.h window.h \
     INTERVAL_SRC blockinput.h $(config_h) 
===================================================================
RCS file: ./src/config.h.in,v
retrieving revision 1.1
diff -b -B -C 3 -r1.1 ./src/config.h.in
*** ./src/config.h.in	1995/12/30 20:02:12	1.1
--- ./src/config.h.in	1996/01/06 05:04:17
***************
*** 183,188 ****
--- 183,195 ----
  /* Define if `struct timeval' is declared by <sys/time.h>.  */
  #undef HAVE_TIMEVAL
  
+ /* Linux console mouse library. */
+ #undef HAVE_LIBGPM
+ 
+ #ifdef HAVE_LIBGPM
+ #define HAVE_MOUSE
+ #endif
+ 
  /* If using GNU, then support inline function declarations. */
  #ifdef __GNUC__
  #define INLINE __inline__
===================================================================
RCS file: ./src/keyboard.c,v
retrieving revision 1.1
diff -b -B -C 3 -r1.1 ./src/keyboard.c
*** ./src/keyboard.c	1995/12/30 21:41:27	1.1
--- ./src/keyboard.c	1996/01/06 05:04:19
***************
*** 51,56 ****
--- 51,58 ----
  #include "syssignal.h"
  #include "systty.h"
  
+ extern int gpm_socket_used;			/* itz 12-31-95, from process.c */
+ 
  /* This is to get the definitions of the XK_ symbols.  */
  #ifdef HAVE_X_WINDOWS
  #include "xterm.h"
***************
*** 3090,3096 ****
  	    pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
  				   &column, &row, NULL, 1);
  
! #ifndef USE_X_TOOLKIT
  	    /* In the non-toolkit version, clicks on the menu bar
  	       are ordinary button events in the event buffer.
  	       Distinguish them, and invoke the menu.
--- 3092,3098 ----
  	    pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
  				   &column, &row, NULL, 1);
  
! #if (!defined(USE_X_TOOLKIT))
  	    /* In the non-toolkit version, clicks on the menu bar
  	       are ordinary button events in the event buffer.
  	       Distinguish them, and invoke the menu.
***************
*** 3098,3104 ****
  	       (In the toolkit version, the toolkit handles the menu bar
  	       and Emacs doesn't know about it until after the user
  	       makes a selection.)  */
! 	    if (row >= 0 && row < FRAME_MENU_BAR_LINES (f))
  	      {
  		Lisp_Object items, item;
  		int hpos;
--- 3100,3106 ----
  	       (In the toolkit version, the toolkit handles the menu bar
  	       and Emacs doesn't know about it until after the user
  	       makes a selection.)  */
! 	    if (!gpm_socket_used && row >= 0 && row < FRAME_MENU_BAR_LINES (f))
  	      {
  		Lisp_Object items, item;
  		int hpos;
***************
*** 6793,6799 ****
  
    kbd_buffer_frame_or_window
      = Fmake_vector (make_number (KBD_BUFFER_SIZE), Qnil);
!   if (!noninteractive && !read_socket_hook && NILP (Vwindow_system))
      {
        signal (SIGINT, interrupt_signal);
  #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
--- 6795,6802 ----
  
    kbd_buffer_frame_or_window
      = Fmake_vector (make_number (KBD_BUFFER_SIZE), Qnil);
!   if (!noninteractive && (!read_socket_hook || gpm_socket_used) &&
! 			NILP (Vwindow_system))
      {
        signal (SIGINT, interrupt_signal);
  #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
===================================================================
RCS file: ./src/sysdep.c,v
retrieving revision 1.1
diff -b -B -C 3 -r1.1 ./src/sysdep.c
*** ./src/sysdep.c	1995/12/31 00:47:18	1.1
--- ./src/sysdep.c	1996/01/06 05:04:20
***************
*** 26,31 ****
--- 25,32 ----
  #include "blockinput.h"
  #undef NULL
  
+ extern int gpm_socket_used;			/* itz 12-31-95, from process.c */
+ 
  #define min(x,y) ((x) > (y) ? (y) : (x))
  
  /* In this file, open, read and write refer to the system calls,
***************
*** 242,248 ****
  
    /* Discarding input is not safe when the input could contain
       replies from the X server.  So don't do it.  */
!   if (read_socket_hook)
      return;
  
  #ifdef VMS
--- 243,249 ----
  
    /* Discarding input is not safe when the input could contain
       replies from the X server.  So don't do it.  */
!   if (read_socket_hook && !gpm_socket_used)
      return;
  
  #ifdef VMS
***************
*** 277,283 ****
  stuff_char (c)
       char c;
  {
!   if (read_socket_hook)
      return;
  
  /* Should perhaps error if in batch mode */
--- 278,284 ----
  stuff_char (c)
       char c;
  {
!   if (read_socket_hook && !gpm_socket_used)
      return;
  
  /* Should perhaps error if in batch mode */
***************
*** 1211,1224 ****
  #endif /* not VMS */
  
  #ifdef BSD_PGRPS
!   if (! read_socket_hook && EQ (Vwindow_system, Qnil))
      narrow_foreground_group ();
  #endif
  
  #ifdef HAVE_X_WINDOWS
    /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
       needs the initialization code below.  */
!   if (!read_socket_hook && EQ (Vwindow_system, Qnil))
  #endif
      {
        EMACS_GET_TTY (input_fd, &old_tty);
--- 1212,1225 ----
  #endif /* not VMS */
  
  #ifdef BSD_PGRPS
!   if ((!read_socket_hook || gpm_socket_used) && EQ (Vwindow_system, Qnil))
      narrow_foreground_group ();
  #endif
  
  #ifdef HAVE_X_WINDOWS
    /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
       needs the initialization code below.  */
!   if ((!read_socket_hook || gpm_socket_used) && EQ (Vwindow_system, Qnil))
  #endif
      {
        EMACS_GET_TTY (input_fd, &old_tty);
***************
*** 1458,1464 ****
  #else
    setbuf (stdout, _sobuf);
  #endif
!   if (! read_socket_hook && EQ (Vwindow_system, Qnil))
      set_terminal_modes ();
  
    if (term_initted && no_redraw_on_reenter)
--- 1459,1465 ----
  #else
    setbuf (stdout, _sobuf);
  #endif
!   if ((!read_socket_hook || gpm_socket_used) && EQ (Vwindow_system, Qnil))
      set_terminal_modes ();
  
    if (term_initted && no_redraw_on_reenter)
***************
*** 1600,1606 ****
  #ifdef HAVE_X_WINDOWS
    /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
       needs the clean-up code below.  */
!   if (read_socket_hook || !EQ (Vwindow_system, Qnil))
      return;
  #endif
    cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0);
--- 1601,1607 ----
  #ifdef HAVE_X_WINDOWS
    /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
       needs the clean-up code below.  */
!   if ((read_socket_hook && !gpm_socket_used) || !EQ (Vwindow_system, Qnil))
      return;
  #endif
    cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0);
===================================================================
RCS file: ./src/term.c,v
retrieving revision 1.1
diff -b -B -C 3 -r1.1 ./src/term.c
*** ./src/term.c	1995/12/31 00:53:00	1.1
--- ./src/term.c	1996/01/06 05:04:21
***************
*** 42,47 ****
--- 42,49 ----
  #define OUTPUT_IF(a) { if (a) tputs (a, FRAME_HEIGHT (selected_frame) - curY, cmputc); }
  #define OUTPUT1_IF(a) { if (a) tputs (a, 1, cmputc); }
  
+ int gpm_socket_used = 0;				/* itz 12-31-95 */
+ 
  /* Terminal characteristics that higher levels want to look at.
     These are all extern'd in termchar.h */
  
===================================================================
RCS file: ./src/gpmevent.c,v
retrieving revision 1.1
diff -b -B -C 3 -r1.1 ./src/gpmevent.c
*** ./src/gpmevent.c	1995/12/31 01:57:49	1.1
--- ./src/gpmevent.c	1996/01/06 05:04:22
***************
*** 1,3 ****
--- 1,413 ----
  /* gpmevent.h */
  /* Linux-specific hooks to handle events from the console mouse library */
  
+ #include <sys/time.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <stdio.h> 
+ #include <values.h> 
+ #include <gpm.h> 
+ #include <errno.h> 
+ #include <signal.h> 
+ #include <config.h>
+ 
+ #include "lisp.h" 
+ #include "window.h" 
+ #include "blockinput.h"					/* itz 12-31-95 do we really need this? */
+ #include "termhooks.h" 
+ #include "termopts.h" 
+ #include "frame.h" 
+ #include "sysselect.h" 
+ #include "syssignal.h" 
+ 
+ /* Because of the way the socket hook is called in read_input_waiting,
+ 	 we give up without a real select(). While we are at it, don't
+ 	 support losing non-posix systems and non-ansi compilers. */
+ #if (!defined(HAVE_SELECT) || !defined(_POSIX_VERSION) || !defined(__STDC__))
+ you lose
+ #endif
+ 
+ #if (!defined(__linux__))				/* possible under xterm */
+ #define KG_SHIFT	0
+ #define KG_CTRL		2
+ #define KG_ALT		3
+ #else
+ #include <linux/keyboard.h> 
+ #endif
+ 
+ #define max(x,y)	((x) < (y) ? (y) : (x))
+ #define GPM_CLICK (GPM_DOWN|GPM_UP)
+ 
+ /* This is a fake, just to distinguish single and multiple clicks */
+ 
+ static unsigned long gpm_timestamp = 1;
+ 
+ /* somebody else may have already hooked read_socket_hook. Be nice and
+ 	 chain to them */
+ 
+ static int (*saved_read_socket_hook)();
+ 
+ /* For communication between the gpm handler and the socket hook. */
+ 
+ static Gpm_Event gpm_event;
+ 
+ /* Set this when we start a drag in the rightmost column of a window,
+ 	 so that we know to provide scroll bar behaviour. */
+ 
+ static int scroll_barring;
+ 
+ /* Pass this to Gpm_Getc. Need to be careful with stdio buffering */
+ 
+ FILE* gpm_file;
+ 
+ /* gpm handling function. this is kind of a joke, because we only want
+ 	 raw mouse events anyway and don't translate them into keypresses;
+ 	 however, the code in keyboard.c that calls us assumes we are going
+ 	 to process both mouse and keyboard input, and so we have to call
+ 	 Gpm_Getchar() not select() and Gpm_GetEvent(). Also we want to
+ 	 support gpmlib's xterm mode, at least in theory. */
+ 
+ static int gpm_mouse_handler(Gpm_Event *event, void *clientdata)
+ {
+ 	gpm_event = *event;
+ 	return  1;
+ }
+ 
+ /* Do this as efficiently as possible. */
+ static Lisp_Object gpm_get_window_and_coordinates (int* w_x, int* w_y,
+ 																									 int* part)
+ {
+ 	Lisp_Object w_first, w_temp;
+ 	w_first = FRAME_SELECTED_WINDOW(selected_frame);			
+ 	w_temp = Fnext_window (w_first, Qt, Qlambda);
+ 	*part = coordinates_in_window (XWINDOW (w_temp), w_x, w_y);
+ 	while (!*part && !EQ(w_temp, w_first)) {
+ 		w_temp = Fnext_window (w_temp, Qt, Qlambda);
+ 		*part = coordinates_in_window (XWINDOW (w_temp), w_x, w_y);
+ 	} /*while*/
+ 	return w_temp;
+ }
+ 
+ static void gpm_get_mouse_pos (FRAME_PTR* f, int insist,
+ 															 Lisp_Object* bar_window,
+ 															 enum scroll_bar_part *part, 
+ 															 Lisp_Object* x, Lisp_Object* y,
+ 															 unsigned long* time) 
+ {
+   *f = selected_frame;
+ 	*time = gpm_timestamp;
+ 	if (!scroll_barring) {
+ 		*bar_window = Qnil;						
+ 		XSETINT(*x, gpm_event.x);
+ 		XSETINT(*y, gpm_event.y);
+ 	}  else {
+ 		int party_dummy;
+ 		int w_x = gpm_event.x, w_y = gpm_event.y;
+ 		*bar_window = gpm_get_window_and_coordinates (&w_x, &w_y, &party_dummy);
+ 		XSETINT(*x, w_y);
+ 		XSETINT(*y, window_internal_height (XWINDOW(*bar_window)));
+ 		*part = scroll_bar_handle;
+ 	} /*if*/
+   mouse_moved = 0;
+ }
+ 
+ /* These are trivial, just as under MSDOG (lifted from there) */
+ 
+ void pixel_to_glyph_coords (FRAME_PTR f, int pix_x, int pix_y, int* x,
+ 														int* y, void* bounds, int noclip)
+ {
+   if (bounds) abort ();
+   /* Ignore clipping.  */
+   *x = pix_x;
+   *y = pix_y;
+ 
+ 	/* argsused f */
+ 	/* argsused noclip */
+ }
+ 
+ void glyph_to_pixel_coords (FRAME_PTR f, int x, int y, int* pix_x,
+ 														int* pix_y)
+ {
+   *pix_x = x;
+   *pix_y = y;
+ }
+ 
+ /* main gpm hook. Mimic XTread_socket but i hope it will be much
+ 	 simpler than that. The waitp/expect arguments to XTread_Socket are
+ 	 ignored -- it never waits */
+ 
+ static int gpm_read_socket (int sd, struct input_event buf [], int bufsize,
+ 										 int waitp, int expected)
+ {
+ 	int nread = 0;
+ 	int c;
+ 
+ 	if (sd != fileno(gpm_file)) {	/* oops, somebody changed the input */
+ 		abort ();										/* descriptor on us. that ain't */
+ 	} /*if*/								    	/* going to work */ 
+ 
+ 	if (saved_read_socket_hook) {
+ 		nread = saved_read_socket_hook (sd, buf, bufsize, waitp,
+ 																		expected);
+ 		if (nread < 0) {
+ 			return  nread;
+ 		} /*if*/
+ 	} /*if*/
+ 
+   if (BLOCK_INPUT) {
+ 		interrupt_input_pending = 1;
+ 		(void) UNBLOCK_INPUT;
+ 		return -1;
+ 	} /*if*/
+ 
+ 	while (nread < bufsize) {
+ 		if (nread >= expected || mouse_moved) {						
+ 			fd_set readfds;				
+ 			struct timeval timeout;
+ 
+ 			FD_ZERO(&readfds);
+ 			FD_SET(sd, &readfds);
+ 			if (gpm_fd >= 0) {
+ 				FD_SET(gpm_fd, &readfds);
+ 			} /*if*/
+ 			timeout.tv_sec = timeout.tv_usec = 0;
+ 			if (!select (max(gpm_fd, sd)+1, &readfds, 0, 0, &timeout)) {
+ 				break;									/* out of while */
+ 			} /*if*/
+ 		} /*if*/
+ 
+ 		c = Gpm_Getc (gpm_file);
+ 		if (!gpm_flag) {						/* connection has gone */
+ 			gpm_hflag = 0;						/* libgpm doesn't do this */
+ 		} /*if*/
+ 		if (gpm_hflag) {						/* it is a click */
+ 
+ 			extern Lisp_Object Vdouble_click_time;
+ 			int i, button = -1;
+ 			int part;
+ 			int w_x, w_y;
+ 			Lisp_Object w_temp;
+ 
+ 			static unsigned char gpm_buttons [] =
+ 					{GPM_B_LEFT, GPM_B_MIDDLE, GPM_B_RIGHT};
+ 			static unsigned char gpm_modifiers [] =
+ 					{1<<KG_SHIFT, 1<<KG_CTRL, 1<<KG_ALT};
+ 			static int emacs_modifiers [] =
+ 					{shift_modifier, ctrl_modifier, meta_modifier};
+ 
+ 			int type = GPM_BARE_EVENTS(gpm_event.type);
+ 
+ 			/* For now, fit all events to the visible screen */
+ 			Gpm_FitEvent (&gpm_event);
+ 
+ 			for (i = 0; i < 3; ++i) {
+ 				if (gpm_event.buttons == gpm_buttons[i]) {
+ 					button = i;
+ 				} /*if*/
+ 			} /*for*/
+ 			if (button == -1) {
+ 				gpm_timestamp += XINT(Vdouble_click_time);
+ 				continue;									/* don't support cords */
+ 			} /*if*/
+ 
+ 			/* First, drags and moves are not reported directly to caller,
+ 				 but polled for by checking mouse_moved */
+ 			if (!(type & GPM_CLICK)) {
+ 				mouse_moved = 1;
+ 				gpm_timestamp += 1;
+ 				continue;								/* back to while */
+ 			} else if (scroll_barring || type == GPM_DOWN)  {
+ 				/* iff this is a click-down in the scroll-bar area, initiate
+ 				 scrollbar mode. */
+ 				w_x = gpm_event.x; w_y = gpm_event.y;
+ 				w_temp = gpm_get_window_and_coordinates (&w_x, &w_y, &part);
+ 				/* strange, mouse click in no window */
+ 				if (!part) {
+ 					abort ();
+ 				} /*if*/
+ 				if (part == 1 &&
+ 						w_x+1 == window_internal_width (XWINDOW(w_temp))) {
+ 					scroll_barring = 1;
+ 				} /*if*/
+ 			}
+ 
+ 			buf[nread].modifiers = 0;
+ 			switch (type) {
+ 			case GPM_DOWN:
+ 				buf[nread].modifiers |= down_modifier;
+ 				gpm_timestamp += (gpm_event.clicks != 0 ? 1 : XINT(Vdouble_click_time));
+ 				if (gpm_fd >= 0) {
+ 					gpm_visiblepointer = 1;
+ 				} /*if*/
+ 				break; 
+ 			case GPM_UP:
+ 				buf[nread].modifiers |= up_modifier;
+ 				gpm_timestamp += 1;
+ 				gpm_visiblepointer = 0;
+ 				break;
+ 			default:
+ 				abort ();										/* can't happen */
+ 			} /*switch*/
+ 
+ 			for (i = 0; i < 3; ++i) {
+ 				if (gpm_event.modifiers & gpm_modifiers[i]) {
+ 					buf[nread].modifiers |= emacs_modifiers[i];
+ 				} /*if*/
+ 			} /*for*/
+ 			buf[nread].code = button;
+ 			buf[nread].timestamp = gpm_timestamp;				
+ 			if (!scroll_barring) {
+ 				buf[nread].kind = mouse_click;
+ 				buf[nread].x = gpm_event.x;
+ 				buf[nread].y = gpm_event.y;
+ 				XSETFRAME(buf[nread].frame_or_window, selected_frame);
+ 			}  else {
+ 				buf[nread].kind = scroll_bar_click;
+ 				buf[nread].part = scroll_bar_handle; /* this is ignored by lisp */
+ 				buf[nread].x = w_y;
+ 				buf [nread].y = window_internal_height (XWINDOW(w_temp));
+ 				buf[nread].frame_or_window = w_temp;
+ 				if (type == GPM_UP) {
+ 					scroll_barring = 0;
+ 				} /*if*/
+ 			} /*if*/
+ 
+ 		}  else {										/* it is a keypress */
+ 
+ 			if (feof(gpm_file)) {
+ 				break;									/* should get SIGHUP */
+ 			}  else  if (ferror(gpm_file)) {
+ 				clearerr (gpm_file);
+ 				if (errno == EAGAIN) {
+ 					continue;							/* back to while */
+ 				} /*if*/
+ 				nread = -1;
+ 				break;									/* something awful */
+ 			} /*if*/
+ 			buf[nread].kind = ascii_keystroke;
+ 			buf[nread].modifiers = 0;
+ 			if (meta_key == 1 && (c & 0x80)) {
+ 				buf[nread].modifiers = meta_modifier;
+ 			} /*if*/
+ 			if (meta_key != 2) {
+ 				c &= ~0x80;
+ 			} /*if*/
+ 			buf[nread].code = c;
+ 			XSETFRAME(buf[nread].frame_or_window, selected_frame);
+ 		} /*if*/
+ 		/* All done! */
+ 		nread += 1;
+ 	} /*while*/
+ 
+ 	(void) UNBLOCK_INPUT;
+ 	return nread;
+ }
+ 
+ #if (defined(SIGTSTP)) 
+ 
+ /* Old SIGTSTP handler. */
+ 
+ static signal_handler_t saved_suspend_hook;
+ 
+ static RETSIGTYPE gpm_suspend_hook ()
+ {
+ 	Gpm_Connect gpm_connect;
+ 	SIGMASKTYPE smask =sigmask (SIGTSTP);
+ 	int success;
+ 
+ 	/* Open a completely transparent gpm connection */
+ 	gpm_connect.eventMask = 0;
+ 	gpm_connect.defaultMask = ~0;
+ 	gpm_connect.minMod = ~0;
+ 	gpm_connect.maxMod = 0;
+ 	/* cannot do this under xterm, tough */
+ 	success = (Gpm_Open (&gpm_connect, 0) >= 0);
+ 
+ 	/* take the default action, whatever it is (probably a stop :) */
+ 	sigunblock (smask);
+ 	signal (SIGTSTP, saved_suspend_hook);
+ 	kill (getpid (), SIGTSTP);
+ 	/* in bardo here */
+ 
+ 	/* Reincarnation. Prepare for another death early. */
+ 	signal (SIGTSTP, gpm_suspend_hook);
+ 	/* Pop the gpm stack by closing the useless connection */
+ 	/* but do it only when we know we opened one.. */
+ 	if (success) {
+ 		Gpm_Close ();
+ 	} /*if*/
+ }
+ #endif
+ 
+ /* do the initialization stuff. This is called from init_process,
+ 	 because it has to set the socket bit in input_wait_mask. */
+ 
+ int init_gpm ()
+ {
+ 	Gpm_Connect gpm_connect;
+ 	int had_keyboard_input;
+ 	extern int input_fd;
+ 	fd_set test_input_fd;
+ 
+ 	/* first, if we are under X graphics, nothing doing. */
+ 	if (noninteractive || !NILP(Vwindow_system)) {
+ 		return 0;
+ 	} /*if*/
+ 
+ 	gpm_file = fdopen(input_fd,"r");
+ 	if (!gpm_file) {
+ 		return 0;
+ 	} /*if*/
+ 	gpm_handler = gpm_mouse_handler;
+ 	gpm_zerobased = 1;
+ 	
+ 	/* Try to open a gpm connection. */
+ 	gpm_connect.eventMask = (GPM_DOWN|GPM_UP|GPM_DRAG);/* this may eventually be overkill, but right now we need it for testing */
+ 	gpm_connect.defaultMask = GPM_MOVE; /* steal drags to prevent highlighting */
+ 	gpm_connect.minMod = 0;
+ 	gpm_connect.maxMod = ((1<<KG_SHIFT)|(1<<KG_ALT)|(1<<KG_CTRL));
+ 	if (Gpm_Open (&gpm_connect, 0) == -1) {
+ 		return 0;
+ 	} /*if*/
+ 
+ 	/* OK, if we got here everything is peachy. setup the event hook and
+ 	 other things */
+ 	saved_read_socket_hook = read_socket_hook;
+ 	read_socket_hook = gpm_read_socket;
+ 	mouse_position_hook = gpm_get_mouse_pos;
+ 	
+ 	FD_ZERO(&test_input_fd);
+ 	FD_SET(input_fd, &test_input_fd);
+ 	had_keyboard_input = keyboard_bit_set (&test_input_fd);
+ 	if (gpm_fd >= 0) {						/* can be -2 for xterm */
+ 		add_keyboard_wait_descriptor (gpm_fd);
+ 	} /*if*/
+ 	if (had_keyboard_input) {
+ 		add_keyboard_wait_descriptor (input_fd);
+ 	} /*if*/
+ 
+ #if (defined(SIGTSTP)) 
+ 	/* Install suspend hook */
+ 	if ((saved_suspend_hook = signal (SIGTSTP, SIG_IGN)) != SIG_IGN) {
+ 		signal (SIGTSTP, gpm_suspend_hook);
+ 	} /*if*/
+ #endif
+ 
+ 	return  1;
+ }
+ 
+ /* Called from redisplay, hopefully after all terminal refresh. */
+ 
+ void gpm_redisplay_pointer ()
+ {
+ 	if (gpm_fd >= 0 && gpm_visiblepointer) {
+ 		GPM_DRAWPOINTER (&gpm_event);
+ 	} /*if*/
+ }
+ 
+ 
+ 
+ /* Local Variables: */
+ /* mode:C */
+ /* tab-width:2 */
+ /* End: */
===================================================================
RCS file: ./src/process.c,v
retrieving revision 1.1
diff -b -B -C 3 -r1.1 ./src/process.c
*** ./src/process.c	1996/01/01 06:13:48	1.1
--- ./src/process.c	1996/01/06 05:04:23
***************
*** 3538,3544 ****
  {
    int fd;
  
!   for (fd = 0; fd < max_keyboard_desc; fd++)
      if (FD_ISSET (fd, mask) && FD_ISSET (fd, &input_wait_mask)
  	&& !FD_ISSET (fd, &non_keyboard_wait_mask))
        return 1;
--- 3538,3545 ----
  {
    int fd;
  
! 	/* itz 01-01-96  A NASTY CRITTER! This was `<' */
!   for (fd = 0; fd <= max_keyboard_desc; fd++)
      if (FD_ISSET (fd, mask) && FD_ISSET (fd, &input_wait_mask)
  	&& !FD_ISSET (fd, &non_keyboard_wait_mask))
        return 1;
***************
*** 3546,3551 ****
--- 3547,3555 ----
    return 0;
  }
  
+ 
+ extern int gpm_socket_used ;				/* itz 12-31-95 */
+ 
  init_process ()
  {
    register int i;
***************
*** 3563,3568 ****
--- 3567,3579 ----
  
    FD_SET (0, &input_wait_mask);
  
+ #if (defined(HAVE_LIBGPM))
+ 	{
+ 		extern int init_gpm();
+ 		gpm_socket_used = init_gpm();
+ 	}
+ #endif
+ 
    Vprocess_alist = Qnil;
    for (i = 0; i < MAXDESC; i++)
      {
===================================================================
RCS file: ./src/xdisp.c,v
retrieving revision 1.1
diff -b -B -C 3 -r1.1 ./src/xdisp.c
*** ./src/xdisp.c	1996/01/04 07:43:30	1.1
--- ./src/xdisp.c	1996/01/06 05:04:25
***************
*** 1129,1134 ****
--- 1129,1138 ----
        windows_or_buffers_changed = 0;
      }
  
+ #if (defined(HAVE_LIBGPM))
+ 		gpm_redisplay_pointer();
+ #endif
+ 	
    /* Start SIGIO interrupts coming again.
       Having them off during the code above
       makes it less likely one will discard output,
===================================================================
RCS file: ./src/window.c,v
retrieving revision 1.1
diff -b -B -C 3 -r1.1 ./src/window.c
*** ./src/window.c	1996/01/05 07:48:56	1.1
--- ./src/window.c	1996/01/06 05:04:27
***************
*** 343,349 ****
     if it is on the window's modeline, return 2;
     if it is on the border between the window and its right sibling,
        return 3.  */
! static int
  coordinates_in_window (w, x, y)
       register struct window *w;
       register int *x, *y;
--- 343,349 ----
     if it is on the window's modeline, return 2;
     if it is on the border between the window and its right sibling,
        return 3.  */
! int
  coordinates_in_window (w, x, y)
       register struct window *w;
       register int *x, *y;
===================================================================
RCS file: ./configure.in,v
retrieving revision 1.1
diff -b -B -C 3 -r1.1 ./configure.in
*** ./configure.in	1995/12/30 18:17:53	1.1
--- ./configure.in	1996/01/06 05:04:27
***************
*** 1234,1239 ****
--- 1234,1244 ----
    AC_DEFINE(HAVE_AIX_SMT_EXP)
  fi
  
+ # itz 12-30-95: check for libgpm on linux
+ if test "${opsys}" = "linux"; then
+ 	AC_CHECK_LIB(gpm, Gpm_Open)
+ fi
+ 
  # Set up the CFLAGS for real compilation, so we can substitute it.
  CFLAGS="$REAL_CFLAGS"
  
